import oss2

class FooderOSSError(RuntimeError):
    def __init__(self, errMsg):
        self.errMsg = errMsg

    def data(self, errDetails):
        self.errDetails = errDetails
        return self

ErrOSSParamNone = FooderOSSError("oss param has None")
ErrOSSFoodBucket = FooderOSSError("oss food_bucket is null and refresh fail")
ErrRedisRuntime = FooderOSSError("oss runtime err")

class OSSUtil:
    def __init__(self, endpoint, bucket_name, context):
        if endpoint is None or bucket_name is None or context is None:
            raise ErrOSSParamNone
        self.endpoint = endpoint
        self.bucket_name = bucket_name
        self.refresh_init(context)
    
    def refresh_init(self, context):
        '''重新初始化'''
        creds = context.credentials
        auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret,
                            creds.security_token)
        self.food_bucket = oss2.Bucket(auth, self.endpoint, self.bucket_name)

    def put_rawImg_object(self, context, file_name, img_raw):
        '''
        上传二进制图片原始数据到oss
        file_name: 可以包含文件路径 eg：商家A/md5.jpg, 路径不存在则创建，文件存在则覆盖
        img_raw: base64.b64decode(base64_img)
        详情可参考: https://help.aliyun.com/document_detail/88426.html?spm=a2c4g.11186623.6.1170.1a407a742L66JU
        '''
        if file_name is None or img_raw is None or context is None:
            raise ErrOSSParamNone
        if self.food_bucket is None:
            self.refresh_init(context)
        if self.food_bucket is None:
            raise ErrOSSFoodBucket
        try:
            result = self.food_bucket.put_object(file_name, img_raw)
            if result.resp.status == 200:
                # return 'https://' + self.bucket_name + '.' + self.endpoint + '/' + file_name
                return file_name
        except Exception as e:
            raise ErrRedisRuntime.data(str(e))

    def get_object(self, context, file_name):
        '''
        获取oss存储对象
        file_name：文件完整路径 eg：商家A/md5.jpg
        下载结果为文件流
        详情可参考: https://help.aliyun.com/document_detail/88441.html?spm=a2c4g.11186623.6.1178.67767ff0Mrk4X7
        '''
        if file_name is None:
            raise ErrOSSParamNone
        if self.food_bucket is None:
            self.refresh_init(context)
        if self.food_bucket is None:
            raise ErrOSSFoodBucket
        try:
            object_stream = self.food_bucket.get_object(file_name)
            return object_stream
        except Exception as e:
            raise ErrRedisRuntime.data(str(e))

    def delete_object(self, context, file_name):
        '''
        删除oss存储对象
        file_name:文件完整路径 eg：商家A/md5.jpg
        '''
        if file_name is None:
            raise ErrOSSParamNone
        if self.food_bucket is None:
            self.refresh_init(context)
        if self.food_bucket is None:
            raise ErrOSSFoodBucket
        try:
            self.food_bucket.delete_object(file_name)
        except Exception as e:
            raise ErrRedisRuntime.data(str(e))
